﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Windows;


namespace WPFDemoMVVM.ViewModel
{

    #region INotifyDataErrorInfo + DataAnnotations 实现属性验证
    public partial class ValueConverterViewModel : ObservableValidator
    {
        private readonly Dictionary<string, List<string>> _errors = new();

        [ObservableProperty]
        [Required(ErrorMessage = "用户名必须不为空")]
        [MinLength(6, ErrorMessage = "用户名长度不能少于6位")]
        [MaxLength(10, ErrorMessage = "用户名长度不能超过10位")]
        private string? userName;

        [ObservableProperty]
        [Required(ErrorMessage = "密码必须不为空")]
        [MinLength(8, ErrorMessage = "密码长度不能少于8位")]
        [MaxLength(20, ErrorMessage = "密码长度不能超过20位")]
        private string? password;

        [ObservableProperty]
        [Range(18, 110, ErrorMessage = "年龄必须在18到110之间")]
        private int age;

        public ValueConverterViewModel()
        {
            PropertyChanged += (s, e) => ValidateProperty(e.PropertyName!);
        }

        private void ValidateProperty(string propertyName)
        {
            if (string.IsNullOrEmpty(propertyName))
                return;

            var propertyInfo = GetType().GetProperty(propertyName);
            if (propertyInfo == null)
                return;

            var context = new ValidationContext(this)
            {
                MemberName = propertyName
            };

            var results = new List<System.ComponentModel.DataAnnotations.ValidationResult>();
            var propertyValue = propertyInfo.GetValue(this);
            Validator.TryValidateProperty(propertyValue, context, results);

            if (_errors.ContainsKey(propertyName))
            {
                _errors.Remove(propertyName);
                OnErrorsChanged(propertyName);
            }

            if (results.Any())
            {
                _errors[propertyName] = results.Select(r => r.ErrorMessage!).ToList();
                OnErrorsChanged(propertyName);
            }
        }

        public bool HasErrors => _errors.Any();

        public event EventHandler<DataErrorsChangedEventArgs>? ErrorsChanged;

        public IEnumerable GetErrors(string? propertyName)
        {
            if (string.IsNullOrEmpty(propertyName))
                return _errors.SelectMany(e => e.Value);
            return _errors.TryGetValue(propertyName, out var errors) ? errors : Enumerable.Empty<string>();
        }

        private void OnErrorsChanged(string propertyName) =>
            ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));

        [RelayCommand(CanExecute = nameof(CanRegister))]
        public void Register()
        {
            MessageBox.Show("注册成功");
        }

        public bool CanRegister() => !HasErrors;
    }


    #endregion



    #region FluentValidation + INotifyDataErrorInfo 实现属性验证

    //public partial class ValueConverterViewModel : ObservableObject, INotifyDataErrorInfo
    //{
    //    private readonly IValidator<ValueConverterViewModel> _validator;
    //    private readonly Dictionary<string, List<string>> _errors = new();

    //    public ValueConverterViewModel()
    //    {
    //        _validator = new ValueConverterViewModelValidator();
    //    }

    //    [ObservableProperty]
    //    private string? userName;

    //    [ObservableProperty]
    //    private int age;

    //    [ObservableProperty]
    //    private string? password;

    //    partial void OnUserNameChanged(string? value)
    //    {
    //        ValidateProperty(nameof(UserName));
    //    }

    //    partial void OnAgeChanged(int value)
    //    {
    //        ValidateProperty(nameof(Age));
    //    }

    //    partial void OnPasswordChanged(string? value)
    //    {
    //        ValidateProperty(nameof(Password));
    //    }

    //    public bool HasErrors => _errors.Any();

    //    public event EventHandler<DataErrorsChangedEventArgs>? ErrorsChanged;

    //    public IEnumerable GetErrors(string? propertyName)
    //    {
    //        if (propertyName != null && _errors.TryGetValue(propertyName, out var errors))
    //        {
    //            return errors;
    //        }
    //        return Enumerable.Empty<string>();
    //    }

    //    private void ValidateProperty(string propertyName)
    //    {
    //        //var context = new ValidationContext<ValueConverterViewModel>(this)
    //        //    .CloneForMember(propertyName);

    //        // 创建只验证特定属性的 ValidatorSelector
    //        var selector = new MemberNameValidatorSelector(new[] { propertyName });

    //        // 正确创建 ValidationContext 并传入 selector
    //        var context = new ValidationContext<ValueConverterViewModel>(this, new PropertyChain(), selector);

    //        var result = _validator.Validate(context);

    //        // 移除旧错误
    //        if (_errors.ContainsKey(propertyName))
    //        {
    //            _errors.Remove(propertyName);
    //            OnErrorsChanged(propertyName);
    //        }

    //        // 添加新错误
    //        var propertyErrors = result.Errors
    //            .Where(e => e.PropertyName == propertyName)
    //            .Select(e => e.ErrorMessage)
    //            .ToList();

    //        if (propertyErrors.Any())
    //        {
    //            _errors[propertyName] = propertyErrors;
    //            OnErrorsChanged(propertyName);
    //        }
    //    }

    //    private void OnErrorsChanged(string propertyName)
    //    {
    //        ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
    //    }

    //    [RelayCommand(CanExecute = nameof(CanRegister))]
    //    public void Register()
    //    {
    //        MessageBox.Show("注册成功");
    //    }

    //    public bool CanRegister() => !HasErrors;

    //}

    #endregion


    #region 使用IDataErrorInfo 实现属性验证

    //public partial class ValueConverterViewModel : ObservableObject, IDataErrorInfo
    //{
    //    private string? userName;
    //    public string? UserName
    //    {
    //        get => userName;
    //        set
    //        {
    //            SetProperty(ref userName, value);
    //            OnPropertyChanged(nameof(Error));
    //        }
    //    }

    //    private int age;
    //    public int Age
    //    {
    //        get => age;
    //        set
    //        {
    //            SetProperty(ref age, value);
    //            OnPropertyChanged(nameof(Error));
    //        }
    //    }

    //    public string Error
    //    {
    //        get
    //        {
    //            var errors = new List<string>
    //            {
    //                this[nameof(UserName)],
    //                this[nameof(Age)],
    //                this[nameof(Password)]
    //            };
    //            return string.Join(Environment.NewLine, errors.Where(t => !string.IsNullOrEmpty(t)));
    //        }
    //    }


    //    private string? password;
    //    public string? Password
    //    {
    //        get => password;
    //        set
    //        {
    //            SetProperty(ref password, value);
    //            OnPropertyChanged(nameof(Error));
    //        }
    //    }


    //    public string this[string columnName]
    //    {
    //        get
    //        {
    //            switch (columnName)
    //            {
    //                case nameof(UserName) when string.IsNullOrWhiteSpace(UserName):
    //                    return "用户名必须不为空";
    //                case nameof(UserName) when UserName.Length is < 6 or > 10:
    //                    return "用户名长度必须在6和10之间";
    //                case nameof(Age) when Age is < 18 or > 110:
    //                    return "年龄必须在18和110之间";
    //                case nameof(Password) when string.IsNullOrWhiteSpace(Password):
    //                    return "密码必须不为空";
    //                case nameof(Password) when Password.Length is < 8 or > 20:
    //                    return "密码长度必须在8和20之间";
    //                default:
    //                    return string.Empty;
    //            }



    //            //if (columnName == nameof(UserName))
    //            //{
    //            //    if (string.IsNullOrEmpty(UserName))
    //            //        return "必须是一个string";
    //            //    if (UserName.Length < 6)
    //            //        return $"长度至少大于{6}";
    //            //    if (UserName.Length > 10)
    //            //        return $"长度至少小于或等于{10}";
    //            //}
    //            //else if (columnName == nameof(Age))
    //            //{
    //            //    if (Age < 18)
    //            //        return "必须是大于或等于18";

    //            //    if (Age> 110)
    //            //        return $"年龄小于110";
    //            //}
    //            //return "";

    //        }
    //    }

    //    [RelayCommand]
    //    public void Register()
    //    {
    //        if (Error.Count() > 0)
    //        {
    //            return;
    //        }
    //        MessageBox.Show("注册成功");
    //    }

    //}
    #endregion


    //public class StringLengthRule : ValidationRule
    //{
    //    public int? MinLength { get; set; }
    //    public int? MaxLength { get; set; }
    //    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    //    {
    //        if (value is not string text)
    //            return new ValidationResult(false, "必须是一个string");
    //        if (MinLength is not null && text.Length < MinLength)
    //            return new ValidationResult(false, $"长度至少大于{MinLength}");
    //        if (MaxLength is not null && text.Length > MaxLength)
    //            return new ValidationResult(false, $"长度至少小于或等于{MaxLength}");
    //        return ValidationResult.ValidResult;
    //    }
    //}

}
